﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Threading;

using Jarvis.Analytics;
using Jarvis.Learners;
using Jarvis.Utility;

using ManagedWinapi;

namespace Jarvis.Windows
{
    /// <summary>
    /// Interaction logic for PreferencesWindow.xaml
    /// </summary>
    public partial class PreferencesWindow : Window
    {
        private Boolean hkInited = false;
        private Hotkey hotkey;

        public LearnerManager learnerManager;

        public void RefreshHotKey()
        {
            Console.WriteLine(" ----- refresh hotkey");

            Preferences p = Preferences.preferences;

            if (p.Get("Use Custom Hotkey") == null)
                p.Set("Use Custom Hotkey", true);

            if (p.Get("Use Custom Hotkey: Control") == null)
                p.Set("Use Custom Hotkey: Control", true);

            if (p.Get("Use Custom Hotkey: Alt") == null)
                p.Set("Use Custom Hotkey: Alt", true);

            if (p.Get("Use Custom Hotkey: Shift") == null)
                p.Set("Use Custom Hotkey: Shift", false);

            if (p.Get("Use Custom Hotkey: Character") == null)
                p.Set("Use Custom Hotkey: Character", "C");

            customHotkey.IsChecked = (Boolean)p.Get("Use Custom Hotkey");

            hkControl.IsChecked = (Boolean)p.Get("Use Custom Hotkey: Control");
            hkAlt.IsChecked = (Boolean)p.Get("Use Custom Hotkey: Alt");
            hkShift.IsChecked = (Boolean)p.Get("Use Custom Hotkey: Shift");
            hkChar.Text = (String)p.Get("Use Custom Hotkey: Character");

            customHotkey.IsChecked = (Boolean)p.Get("Use Custom Hotkey");

            if ((bool) p.Get("Use Custom Hotkey"))
            {
                hkControl.IsEnabled = true;
                hkAlt.IsEnabled = true;
                hkShift.IsEnabled = true;

                hkChar.IsEnabled = true;
            }
            else
            {
                hkControl.IsEnabled = false;
                hkAlt.IsEnabled = false;
                hkShift.IsEnabled = false;

                hkChar.IsEnabled = false;
            }

            if (hotkey == null)
            {
                hotkey = new Hotkey();
                hotkey.HotkeyPressed += new EventHandler((Application.Current as App).hotkey_HotkeyPressed);
            }

            hotkey.Enabled = false;

            if ((bool)p.Get("Use Custom Hotkey"))
            {
                hotkey.Alt = (Boolean)p.Get("Use Custom Hotkey: Alt");
                hotkey.Ctrl = (Boolean)p.Get("Use Custom Hotkey: Control");
                hotkey.Shift = (Boolean)p.Get("Use Custom Hotkey: Shift");

                KeyConverter converter = new KeyConverter();

                Key code = (Key)converter.ConvertFromString((p.Get("Use Custom Hotkey: Character") as String));

                hotkey.KeyCode = (System.Windows.Forms.Keys)KeyInterop.VirtualKeyFromKey(code);

                try
                {
                    hotkey.Enabled = true;
                }
                catch (ManagedWinapi.HotkeyAlreadyInUseException)
                {
                    System.Windows.MessageBox.Show("The selected hotkey is already in use. Please select another in the preferences.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
                hotkey.Enabled = false;
        }

        public PreferencesWindow()
        {
            InitializeComponent();

            Preferences p = Preferences.preferences;

            if (p.Get("Log Analytics") != null)
                analytics.IsChecked = (Boolean)p.Get("Log Analytics");

            if (p.Get("Use System Notification Area") != null)
                systray.IsChecked = (Boolean)p.Get("Use System Notification Area");

            this.RefreshHotKey();

            hkInited = true;
        }

        private void Window_Closing(object sender, CancelEventArgs e)
        {
            Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                (DispatcherOperationCallback)delegate(object o)
                {
                    Hide();
                    return null;
                }, null);

            AnalyticsManager.LogEvent("Window Closing", "Preferences");

            e.Cancel = true;
        }

        private void analytics_Checked(object sender, RoutedEventArgs e)
        {
            Preferences.preferences.Set("Log Analytics", analytics.IsChecked);
        }

        private void systray_Checked(object sender, RoutedEventArgs e)
        {
            Preferences.preferences.Set("Use System Notification Area", systray.IsChecked);
        }

        private void hkChanged(object sender, RoutedEventArgs e)
        {
            if (!hkInited)
                return;

            Preferences p = Preferences.preferences;

            p.Set("Use Custom Hotkey", customHotkey.IsChecked);

            p.Set("Use Custom Hotkey: Control", hkControl.IsChecked);
            p.Set("Use Custom Hotkey: Alt", hkAlt.IsChecked);
            p.Set("Use Custom Hotkey: Shift", hkShift.IsChecked);
            p.Set("Use Custom Hotkey: Character", hkChar.Text);

            this.RefreshHotKey();
        }

        private void typeCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            String selection = (typeCombo.SelectedValue as ComboBoxItem).Content.ToString();

            labelCombo.Items.Clear();
            newLabelCombo.Items.Clear();

            List<String> labels = null;

            if (selection.Equals("Activity"))
                labels = (Preferences.preferences.Get("Activity Labels") as List<String>);
            else if (selection.Equals("Location"))
                labels = (Preferences.preferences.Get("Location Labels") as List<String>);
            else if (selection.Equals("Social Context"))
                labels = (Preferences.preferences.Get("Social Labels") as List<String>);
            else
                labels = new List<string>();

            labels.Sort();

            foreach (string s in labels)
            {
                labelCombo.Items.Add(s);
                newLabelCombo.Items.Add(s);
            }

            labelCombo.SelectedIndex = 0;
            newLabelCombo.SelectedIndex = -1;
        }

        private void labelCombo_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                String selection = labelCombo.SelectedValue.ToString();

                deleteButton.Content = "Delete \"" + selection + "\"";
                renameButton.Content = "Rename \"" + selection + "\"";
            }
            catch (NullReferenceException)
            {
                deleteButton.Content = "Delete \"Label\"";
                renameButton.Content = "Rename \"Label\"";
            }
        }

        private void updateButton_Click(object sender, RoutedEventArgs e)
        {
            Console.WriteLine("Update Labels Button Pushed");

            String oldLabel = labelCombo.SelectedValue.ToString();
            String newLabel = newLabelCombo.Text;
            String selection = (typeCombo.SelectedValue as ComboBoxItem).Content.ToString();

            if (deleteButton.IsChecked == true)
            {
                if (MessageBoxResult.Yes == System.Windows.MessageBox.Show("Are you sure that you wish to delete all training examples labeled \"" + oldLabel + "\"?", "Confirm Deletion", MessageBoxButton.YesNo, MessageBoxImage.Warning))
                    learnerManager.DeleteLabelForLearner(selection, oldLabel);
            }
            else if (newLabel != null && !newLabel.Equals(""))
            {
                if (MessageBoxResult.Yes == System.Windows.MessageBox.Show("Are you sure that you wish to rename all training examples labeled \"" + oldLabel + "\"?", "Confirm Rename", MessageBoxButton.YesNo, MessageBoxImage.Warning))
                    learnerManager.RenameLabelForLearner(selection, oldLabel, newLabel);
            }

            this.typeCombo_SelectionChanged(sender, null);
        }
    }
}
